home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / utilwb / lupe.lha / source / lupe.c next >
C/C++ Source or Header  |  1996-04-08  |  38KB  |  1,284 lines

  1. // Lupe V1.4 - 1995-96 - © Frank Toepper
  2. // a lens
  3. // AmigaOS 3.0+
  4. // Maxon C++ V3
  5. // last changes: 8.4.96
  6.  
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <stream.h>
  10. #include <intuition/intuition.h>
  11. #include <intuition/imageclass.h>
  12. #include <intuition/icclass.h>
  13. #include <intuition/gadgetclass.h>
  14. #include <intuition/intuitionbase.h>
  15. #include <exec/exec.h>
  16. #include <dos/dos.h>
  17. #include <graphics/scale.h>
  18. #include <devices/inputevent.h>
  19. #include <libraries/commodities.h>
  20. #include <libraries/gadtools.h>
  21. #include <graphics/displayinfo.h>
  22. #include <graphics/gfxmacros.h>
  23. #include <graphics/gfxbase.h>
  24. #include <cybergraphics/cybergraphics.h>
  25. #include <clib/dos_protos.h>
  26. #include <clib/intuition_protos.h>
  27. #include <clib/graphics_protos.h>
  28. #include <clib/exec_protos.h>
  29. #include <clib/commodities_protos.h>
  30. #include <clib/gadtools_protos.h>
  31. #include <clib/icon_protos.h>
  32. #include <clib/cybergraphics_protos.h>
  33. #include <pragma/cybergraphics_lib.h>
  34. #include <wbstartup.h>
  35.  
  36. #pragma header
  37.  
  38. #define CYBERARRAY_BPP 3
  39. #define MINWIDTH 88
  40. #define MINHEIGHT 30
  41.  
  42. WORD innerwidth = 150, innerheight = 100, sourcewidth, sourceheight;
  43. WORD scalefac = 5, maxscalefac = 15, minwidth, fixedX = 0, fixedY = 0;
  44. WORD leftoff, topoff, bottomoff, rightoff;
  45. WORD sizeiw, sizeih, winx, winy, winleft = 0, wintop = 11, originX = 0, originY = 0;
  46. WORD textoff;
  47. ULONG cxsigflag, scrdepth;
  48. LONG waitmask, pens[4] = {2, 3, 1, 0};
  49. APTR VisualInfo, cyberdata = NULL;
  50. struct MsgPort *broker_mp, *userport;
  51. struct Task *thistask;
  52. struct Window *mywin;
  53. struct Screen *scr = NULL, *tmpscr;
  54. struct Menu *menu = NULL;
  55. struct MenuItem *item;
  56. struct BitMap *srcbm = NULL, *destbm = NULL, *scrbm;
  57. struct TextFont *screenfont = NULL, *topazfont;
  58. struct InputXpression setoriginix, resetoriginix;
  59. struct RastPort *scrrp, destrp, *winrp;
  60. struct Library *CxBase, *GfxBase, *GadToolsBase, *CyberGfxBase, *IconBase;
  61. BYTE timesig;
  62. BOOL hires, newlook, jump = FALSE, fast = FALSE, pubscreenlocked = FALSE, enable = TRUE;
  63. BOOL cybergfxscreen, coords = FALSE, crosshair = FALSE, origin = TRUE, fixed = FALSE, jumpdirect;
  64. CxObj *broker, *customcxobj;
  65. Object *propgadget;
  66. char pubscreenname[MAXPUBSCREENNAME];
  67. char coordstring[12], setoriginkey[50] = "lalt o", resetoriginkey[50] = "lalt r";
  68. char title[10];
  69. char *Template = "CX_PRIORITY=P/N/K,FAST=F/S/K,MAXSCALEFACTOR=M/N/K,SCALEFACTOR=S/N/K,"
  70.                  "WINLEFT=L/N/K,WINTOP=T/N/K,WINWIDTH=W/N/K,WINHEIGHT=H/N/K,"
  71.                  "COORDINATES=C/S/K,CROSSHAIR=R/S/K,SETORIGINKEY=O/K,RESETORIGINKEY=K/K,FIXED=D/S/K";
  72.  
  73. extern struct IntuitionBase *IntuitionBase;
  74.  
  75. // functions declaration for menu
  76. BOOL jumpFunc ();
  77. BOOL fastFunc ();
  78. BOOL AboutFunc ();
  79. BOOL enableFunc ();
  80. BOOL coordsFunc ();
  81. BOOL crosshairFunc ();
  82. BOOL fixedFunc ();
  83. BOOL QuitFunc ();
  84.  
  85. struct EasyStruct es_about = {
  86.    20, 0,
  87.    "Lupe",
  88.    "%s",
  89.    "%s"
  90. };
  91.  
  92. char *era_about[] = {
  93.    "Lupe V1.4 (" __DATE__ ")\n\n"
  94.    "written by:\n"
  95.    "  Frank Toepper\n"
  96.    "  Maxim Gorki Strasse 5A\n"
  97.    "  Greifswald\n"
  98.    "  17491\n"
  99.    "  GERMANY\n\n"
  100.    "EMail:\n"
  101.    "  toepper@rz.uni-greifswald.de\n\n"
  102.    "This program is Public Domain", 
  103.    "Ok"
  104. };
  105.  
  106. struct NewBroker newbroker = {
  107.    NB_VERSION,
  108.    "Lupe",
  109.    "Lupe V1.4 © 1995-96 Frank Toepper",
  110.    "A magnifing glass program.",
  111.    3,
  112.    0,
  113.    0,
  114.    NULL,
  115.    0
  116. };
  117.  
  118. struct BitScaleArgs bsa = {
  119.    // Src Koords
  120.    0, 0,
  121.    innerwidth / scalefac,
  122.    innerheight / scalefac,
  123.    // Src Faktoren
  124.    1, 1,
  125.    0, 0,
  126.    innerwidth,
  127.    innerheight,
  128.    // Dest Faktoren
  129.    scalefac, scalefac,
  130.    // Bitmaps
  131.    NULL, NULL,
  132.    0,
  133.    0, 0,
  134.    0, 0
  135. };
  136.  
  137. struct TextAttr topaz_attr = {
  138.    "topaz.font",
  139.    8,
  140.    0,
  141.    FPF_ROMFONT
  142. };
  143.  
  144. void Putchar (register __d0 char zeichen, register __a3 char *putchdata)
  145. {
  146.    *putchdata++ = zeichen;
  147. }
  148.  
  149. void error (char *formatstring, ...)
  150. {
  151.  APTR args = &formatstring + 1;
  152.  struct EasyStruct easystruct = {
  153.     sizeof (struct EasyStruct), 
  154.     0, 
  155.     "Error", 
  156.     formatstring, 
  157.     "Ok"
  158.  };
  159.  
  160.    if (Cli ())
  161.    {
  162.       VPrintf (formatstring, args);
  163.       FPutC (Output (), '\n');
  164.       Flush (Output ());
  165.    }
  166.    else
  167.    {
  168.       EasyRequestArgs (NULL, &easystruct, NULL, args);
  169.    }
  170. }
  171.  
  172. BOOL lockaspublicscreen (struct Screen *screen)
  173. {
  174.  struct List *pubscreenlist;
  175.  struct PubScreenNode *pubscreennode;
  176.  
  177.    if (pubscreenlist = LockPubScreenList ())
  178.    {
  179.       pubscreennode = (struct PubScreenNode *) pubscreenlist->lh_Head;
  180.       while (pubscreennode)
  181.       {
  182.          if (pubscreennode->psn_Screen == screen)
  183.          {
  184.             if (LockPubScreen (pubscreennode->psn_Node.ln_Name))
  185.             {
  186.                UnlockPubScreenList ();
  187.                return TRUE;
  188.             }
  189.          }
  190.          pubscreennode = (struct PubScreenNode *) pubscreennode->psn_Node.ln_Succ;
  191.       }
  192.       UnlockPubScreenList ();
  193.    }
  194.    return FALSE;
  195. }
  196.  
  197. int setupscreen (struct Screen *selectedscreen)
  198. {
  199.  ULONG id;
  200.  
  201.    jumpdirect = FALSE;
  202.    if (selectedscreen)
  203.    {
  204.       jumpdirect = TRUE;
  205.       if (scr)
  206.       {
  207.          FreeVisualInfo (VisualInfo);
  208.          if (pubscreenlocked)
  209.          {
  210.             UnlockPubScreen (NULL, scr);
  211.          }
  212.       }
  213.       if (lockaspublicscreen (selectedscreen)) pubscreenlocked = TRUE;
  214.       else pubscreenlocked = FALSE;
  215.       scr = selectedscreen;
  216.    }
  217.    else if (scr)
  218.    {
  219.       if (tmpscr = scr->NextScreen)
  220.       {
  221.          FreeVisualInfo (VisualInfo);
  222.          VisualInfo = NULL;
  223.          if (pubscreenlocked)
  224.          {
  225.             UnlockPubScreen (NULL, scr);
  226.             pubscreenlocked = FALSE;
  227.          }
  228.          if (lockaspublicscreen (tmpscr)) pubscreenlocked = TRUE;
  229.       }
  230.       else
  231.       {
  232.          error ("There is no other screen.");
  233.          return 1;  // not real an error
  234.       }
  235.       scr = tmpscr;
  236.    }
  237.    else if (scr = LockPubScreen (NULL))
  238.    {
  239.       pubscreenlocked = TRUE;
  240.    }
  241.    else
  242.    {
  243.       error ("Can't lock publicscreen.");
  244.       return 2;
  245.    }
  246.    if (!(VisualInfo = GetVisualInfoA (scr, NULL)))
  247.    {
  248.       error ("Can't get visualinfo from screen.");
  249.       return 3;
  250.    }
  251.    cybergfxscreen = FALSE;
  252.    if (CyberGfxBase)
  253.       if ((id = GetVPModeID (&scr->ViewPort)) != INVALID_ID)
  254.          if (IsCyberModeID (id))
  255.             if (GetCyberIDAttr (CYBRIDATTR_BPPIX, id) > 1)
  256.                cybergfxscreen = TRUE;
  257.    return 0;
  258. }
  259.  
  260. void CloseDownScreen ()
  261. {
  262.    if (VisualInfo)
  263.    {
  264.       FreeVisualInfo (VisualInfo);
  265.       VisualInfo = NULL;
  266.    }
  267.    if (scr && pubscreenlocked)
  268.    {
  269.       UnlockPubScreen (NULL, scr);
  270.       scr = NULL;
  271.    }
  272. }
  273.  
  274. void getoffsets ()
  275. {
  276.  struct DrawInfo *drawinfo;
  277.  APTR sizeobject;
  278.  ULONG attr;
  279.    
  280.    if (screenfont)
  281.    {
  282.       CloseFont (screenfont);
  283.       screenfont = NULL;
  284.    }
  285.    hires = (scr->Flags & SCREENHIRES) != 0;
  286.    hires ? (rightoff = 18) : (rightoff = 13);
  287.    if (drawinfo = GetScreenDrawInfo (scr))
  288.    {
  289.       if (sizeobject = NewObject (NULL, SYSICLASS,
  290.        SYSIA_Which, SIZEIMAGE,
  291.        SYSIA_DrawInfo, drawinfo,
  292.        SYSIA_Size, hires ? SYSISIZE_MEDRES : SYSISIZE_LOWRES,
  293.        TAG_END))
  294.       {
  295.          if (GetAttr (IA_Width, sizeobject, &attr))
  296.          {
  297.             sizeiw = attr;
  298.             rightoff =  (UWORD) attr;
  299.          }
  300.          if (GetAttr (IA_Height, sizeobject, &attr))
  301.          {
  302.             sizeih = attr;
  303.          }
  304.          newlook = (drawinfo->dri_Flags & DRIF_NEWLOOK) && (drawinfo->dri_Depth != 1);
  305.          DisposeObject (sizeobject);
  306.       }
  307.       pens[0] = drawinfo->dri_Pens[FILLTEXTPEN];
  308.       pens[1] = drawinfo->dri_Pens[FILLPEN];
  309.       pens[2] = drawinfo->dri_Pens[TEXTPEN];
  310.       pens[3] = drawinfo->dri_Pens[BACKGROUNDPEN];
  311.       FreeScreenDrawInfo (scr, drawinfo);
  312.    }
  313.    scrrp = &scr->RastPort;
  314.    topoff = scrrp->TxHeight + (UWORD) scr->WBorTop + 1;
  315.    leftoff = scr->WBorLeft;
  316.    scrbm = scrrp->BitMap;
  317.    scrdepth = GetBitMapAttr (scrbm, BMA_DEPTH);
  318.    minwidth = MINWIDTH;
  319.    if (coords)
  320.    {
  321.       bottomoff = sizeih;
  322.       // center the text in the bottomborder
  323.       textoff = (bottomoff + topazfont->tf_YSize >> 1) - topazfont->tf_Baseline;
  324.       // SysIHack or height of screenfont <= 8?
  325.       if ((bottomoff - 2) >= scr->Font->ta_YSize)
  326.       {
  327.          if (screenfont = OpenFont (scr->Font))
  328.          {
  329.             minwidth = 11 * (screenfont->tf_XSize);
  330.             // center the text in the bottomborder
  331.             textoff = (bottomoff + screenfont->tf_YSize >> 1) - screenfont->tf_Baseline;
  332.          }
  333.       }
  334.    }
  335.    else bottomoff = scr->WBorBottom;
  336. }
  337.  
  338. void setwintitle ()
  339. {
  340.  LONG args[] = { (LONG) "Lupe", scalefac };
  341.  
  342.    RawDoFmt ("%s %ld:1", args, (void (*)()) Putchar, title);
  343.    SetWindowTitles (mywin, title, (STRPTR) ~0);
  344. }
  345.  
  346. int allocbm ()
  347. {
  348.    if (destbm) FreeBitMap (destbm);
  349.    if (srcbm) FreeBitMap (srcbm);
  350.    destbm = srcbm = NULL;
  351.    if (cyberdata) FreeVec (cyberdata);
  352.    cyberdata = NULL;
  353.    winx = mywin->Width;
  354.    winy = mywin->Height;
  355.    innerwidth = winx - (leftoff + rightoff);
  356.    innerheight = winy - (topoff + bottomoff);
  357.    sourcewidth = innerwidth / scalefac;
  358.    sourceheight = innerheight / scalefac;
  359.    if (scalefac > 1)
  360.    {
  361.       if (cybergfxscreen)
  362.       {
  363.          if (!(cyberdata = AllocVec (sourcewidth * sourceheight * CYBERARRAY_BPP, MEMF_PUBLIC)))
  364.          {
  365.             error ("Can't allocate %ld Bytes for CyberPixelArray.", sourcewidth * sourceheight * CYBERARRAY_BPP);
  366.             return 1;
  367.          }
  368.          if (!(destbm = AllocBitMap (innerwidth, innerheight, scrdepth, BMF_CLEAR | BMF_MINPLANES, scrbm)))
  369.          {
  370.             error ("'AllocBitMap' for destination bitmap failed.");
  371.             return 3;
  372.          }
  373.       }
  374.       else
  375.       {
  376.          if (!(srcbm = AllocBitMap (sourcewidth, sourceheight, scrdepth, BMF_CLEAR, scrbm)))
  377.          {
  378.             error ("'AllocBitMap' for source bitmap failed.");
  379.             return 2;
  380.          }
  381.          if (!(destbm = AllocBitMap (innerwidth, innerheight, scrdepth, BMF_CLEAR, scrbm)))
  382.          {
  383.             error ("'AllocBitMap' for destination bitmap failed.");
  384.             return 3;
  385.          }
  386.          bsa.bsa_SrcWidth = sourcewidth;
  387.          bsa.bsa_SrcHeight = sourceheight;
  388.          bsa.bsa_DestWidth = innerwidth;
  389.          bsa.bsa_DestHeight = innerheight;
  390.          bsa.bsa_SrcBitMap = srcbm;
  391.          bsa.bsa_DestBitMap = destbm;
  392.          bsa.bsa_XDestFactor = bsa.bsa_YDestFactor = scalefac;
  393.       }
  394.       destrp.BitMap = destbm;
  395.    }
  396.    return 0;
  397. }
  398.  
  399. BOOL makescreensmenu ()
  400. {
  401.  struct NewMenu tmpmenu[] = {
  402.   { NM_SUB, 0, 0, 0, 0, 0 }, 
  403.   { NM_END, 0, 0, 0, 0, 0 }
  404.  };
  405.  ULONG lock;
  406.  struct List *pubscreenlist;
  407.  struct PubScreenNode *pubscreennode;
  408.  struct MenuItem **itempointer = &menu->FirstItem->NextItem->SubItem;
  409.  int i = 0;
  410.  
  411.    lock = LockIBase (0);
  412.    tmpscr = IntuitionBase->FirstScreen;
  413.    if (tmpscr->NextScreen)
  414.    {
  415.       while (tmpscr = tmpscr->NextScreen)
  416.       {
  417.          tmpmenu[0].nm_Label = tmpscr->DefaultTitle;
  418.          if (pubscreenlist = LockPubScreenList ())
  419.          {
  420.             pubscreennode = (struct PubScreenNode *) pubscreenlist->lh_Head;
  421.             while (pubscreennode)
  422.             {
  423.                if (pubscreennode->psn_Screen == tmpscr)
  424.                {
  425.                   tmpmenu[0].nm_Label = pubscreennode->psn_Node.ln_Name;
  426.                   break;
  427.                }
  428.                pubscreennode = (struct PubScreenNode *) pubscreennode->psn_Node.ln_Succ;
  429.             }
  430.             UnlockPubScreenList ();
  431.          }
  432.          tmpmenu[0].nm_UserData = tmpscr;
  433.          // each item single created
  434.          if (*itempointer = (struct MenuItem *) CreateMenusA (tmpmenu, NULL))
  435.          {
  436.             itempointer = &(*itempointer)->NextItem;
  437.          }
  438.          else error ("Can't create a screensmenu item.");
  439.       }
  440.    }
  441.    else
  442.    {
  443.       tmpmenu[0].nm_Label = "No Other Screen";
  444.       if (*itempointer = (struct MenuItem *) CreateMenusA (tmpmenu, NULL))
  445.       {
  446.          (*itempointer)->Flags |= HIGHNONE;
  447.          itempointer = &(*itempointer)->NextItem;
  448.       }
  449.       else error ("Can't create screensmenu.");
  450.    }
  451.    UnlockIBase (lock);
  452.    if (LayoutMenus (menu, VisualInfo, GTMN_NewLookMenus, TRUE, TAG_DONE))
  453.    {
  454.       return TRUE;
  455.    }
  456.    else error ("Can't layout screensmenu.");
  457.    return FALSE;
  458. }
  459.  
  460. void freescreensmenu (struct MenuItem *menuitem)
  461. {
  462.    if (menuitem)
  463.    {
  464.       freescreensmenu (menuitem->NextItem);
  465.       FreeMenus ((struct Menu *) menuitem);
  466.    }
  467. }
  468.  
  469. BOOL openwin ()
  470. {
  471.  ULONG lock;
  472.  WORD bw, rh;
  473.  struct Rectangle zoom = {
  474.     minwidth + leftoff + rightoff,
  475.     MINHEIGHT + topoff + bottomoff + sizeih,
  476.     -1, -1
  477.  };
  478.  struct NewMenu standartmenu[] = {
  479.    { NM_TITLE, "Project",        0, 0, 0, 0 },
  480.    {  NM_ITEM, "Jump",           "J", 0, 0, jumpFunc },
  481.    {  NM_ITEM, "Jump To Screen", 0, 0, 0, 0 },
  482.    {  NM_ITEM, NM_BARLABEL,      0, 0, 0, 0 },
  483.    {  NM_ITEM, "Enable",         "E", (enable ? CHECKED : 0) | CHECKIT | MENUTOGGLE, 0, enableFunc },
  484.    {  NM_ITEM, "Fixed",          "D", (fixed ? CHECKED : 0) | CHECKIT | MENUTOGGLE, 0, fixedFunc },
  485.    {  NM_ITEM, "Fast",           "F", (fast ? CHECKED : 0) | CHECKIT | MENUTOGGLE, 0, fastFunc },
  486.    {  NM_ITEM, "Coordinates",    "C", (coords ? CHECKED : 0) | CHECKIT | MENUTOGGLE, 0, coordsFunc },
  487.    {  NM_ITEM, "Crosshair",      "R", (crosshair ? CHECKED : 0) | CHECKIT | MENUTOGGLE, 0, crosshairFunc },
  488.    {  NM_ITEM, NM_BARLABEL,      0, 0, 0, 0 },
  489.    {  NM_ITEM, "About",          "?", 0, 0, AboutFunc },
  490.    {  NM_ITEM, NM_BARLABEL,      0, 0, 0, 0 },
  491.    {  NM_ITEM, "Quit",           "Q", 0, 0, QuitFunc },
  492.    {  NM_END, 0, 0, 0, 0, 0 }
  493.  };
  494.  
  495.    if (hires) bw = rh = 2;
  496.    else bw = rh = 1;
  497.    // first bring the screen to front
  498.    //  -> screen order in menu correct
  499.    lock = LockIBase (0);
  500.    tmpscr = IntuitionBase->FirstScreen;
  501.    UnlockIBase (lock);
  502.    if (tmpscr != scr)
  503.    {
  504.       if (jumpdirect) ScreenToFront (scr);
  505.       else ScreenToBack (tmpscr);
  506.    }
  507.    if (menu = CreateMenusA (standartmenu, NULL))
  508.    {
  509.       if (makescreensmenu ())
  510.       {
  511.          if (propgadget = (Object *) NewObject (NULL, PROPGCLASS,
  512.           PGA_Freedom,     FREEVERT,
  513.           ICA_TARGET,      ICTARGET_IDCMP,
  514.           PGA_NewLook,     TRUE,
  515.           PGA_Borderless,  newlook,
  516.           PGA_Total,       maxscalefac,
  517.           PGA_Visible,     1,
  518.           PGA_Top,         scalefac - 1,
  519.           GA_RelRight,     bw - sizeiw + 3,
  520.           GA_Top,          topoff + rh,
  521.           GA_Width,        sizeiw - bw - bw - 4,
  522.           GA_RelHeight,    -topoff - sizeih - rh - rh,
  523.           GA_RightBorder,  TRUE,
  524.           TAG_DONE))
  525.          {
  526.             if (mywin = OpenWindowTags (NULL,
  527.              WA_Flags,          WFLG_ACTIVATE | WFLG_CLOSEGADGET | WFLG_DEPTHGADGET | WFLG_DRAGBAR
  528.                                  | WFLG_SIZEGADGET | WFLG_SIMPLE_REFRESH | WFLG_NEWLOOKMENUS
  529.                                  | WFLG_NOCAREREFRESH | WFLG_REPORTMOUSE
  530.                                  | WFLG_SIZEBRIGHT | (coords ? WFLG_SIZEBBOTTOM : 0),
  531.              WA_AutoAdjust,     1,
  532.              WA_MaxHeight,      -1,
  533.              WA_MaxWidth,       -1,
  534.              WA_MinHeight,      MINHEIGHT + topoff + bottomoff,
  535.              WA_MinWidth,       minwidth + leftoff + rightoff,
  536.              WA_IDCMP,          IDCMP_CLOSEWINDOW | IDCMP_IDCMPUPDATE | IDCMP_NEWSIZE | IDCMP_MENUPICK
  537.                                  | IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW | IDCMP_MOUSEBUTTONS
  538.                                  | IDCMP_MOUSEMOVE | IDCMP_VANILLAKEY | IDCMP_RAWKEY,
  539.              WA_InnerHeight,    innerheight,
  540.              WA_InnerWidth,     innerwidth,
  541.              WA_Left,           winleft,
  542.              WA_Gadgets,        propgadget,
  543.              WA_Top,            wintop,
  544.              WA_PubScreen,      scr,
  545.              WA_Zoom,           &zoom,
  546.              TAG_DONE))
  547.             {
  548.                // shit patches
  549.                leftoff = mywin->BorderLeft;
  550.                bottomoff = mywin->BorderBottom;
  551.                SetMenuStrip (mywin, menu);
  552.                setwintitle ();
  553.                userport = mywin->UserPort;
  554.                winrp = mywin->RPort;
  555.                if (screenfont) SetFont (winrp, screenfont);
  556.                else SetFont (winrp, topazfont);
  557.                SetAPen (winrp, pens[0]);
  558.                SetBPen (winrp, pens[1]);
  559.                return TRUE;
  560.             }
  561.             else error ("Can't open window.");
  562.          }
  563.          else error ("Can't create propgadget.");
  564.       }
  565.    }
  566.    else error ("Can't create menu.");
  567.    return FALSE;
  568. }
  569.  
  570. void closewin ()
  571. {
  572.    if (menu) ClearMenuStrip (mywin);
  573.    CloseWindow (mywin);
  574.    if (menu)
  575.    {
  576.       freescreensmenu (ItemAddress (menu, FULLMENUNUM (0, 1, 0)));
  577.       FreeMenus (menu);
  578.       menu = NULL;
  579.    }
  580.    DisposeObject (propgadget);
  581.    if (srcbm) FreeBitMap (srcbm);
  582.    if (destbm) FreeBitMap (destbm);
  583.    if (cyberdata) FreeVec (cyberdata);
  584.    srcbm = NULL;
  585.    destbm = NULL;
  586.    cyberdata = NULL;
  587. }
  588.  
  589. void refresh ()
  590. {
  591.  WORD x, y, xoff = 0, yoff = 0;
  592.  
  593.    if (fixed)
  594.    {
  595.       x = fixedX;
  596.       y = fixedY;
  597.    }
  598.    else
  599.    {
  600.       x = scr->MouseX;
  601.       y = scr->MouseY;
  602.    }
  603.    // print the coordinates
  604.    if (coords)
  605.    {
  606.       LONG args[] = {x - originX, y - originY};
  607.       memset (coordstring, ' ', 11);
  608.       RawDoFmt ("%ld,%ld", args, (void (*)()) Putchar, coordstring);
  609.       coordstring[strlen (coordstring)] = ' ';
  610.       Move (winrp, leftoff, mywin->Height - textoff);
  611.       Text (winrp, coordstring, 11);
  612.    }
  613.    // adjust the coordinates
  614.    x -= sourcewidth >> 1;
  615.    y -= sourceheight >> 1;
  616.    if (x < 0)
  617.    {
  618.       xoff = x;
  619.       x = 0;
  620.    }
  621.    else if (x > (scr->Width - sourcewidth))
  622.    {
  623.       xoff = -(scr->Width - sourcewidth - x);
  624.       x = scr->Width - sourcewidth;
  625.    }
  626.    if (y < 0)
  627.    {
  628.       yoff = y;
  629.       y = 0;
  630.    }
  631.    else if (y > (scr->Height - sourceheight))
  632.    {
  633.       yoff = -(scr->Height - sourceheight - y);
  634.       y = scr->Height - sourceheight;
  635.    }
  636.    // calculate the crosshair
  637.    if (crosshair)
  638.    {
  639.       xoff = scalefac * ((sourcewidth >> 1) + xoff) + (scalefac >> 1);
  640.       yoff = scalefac * ((sourceheight >> 1) + yoff) + (scalefac >> 1);
  641.    }
  642.    if (scalefac > 1)
  643.    {
  644.       // blit and scale
  645.       if (cybergfxscreen)
  646.       {
  647.          // BitMapScale don't work with bitmaps >8 Bit (CyberGfx 2.15)
  648.          ReadPixelArray (cyberdata, 0, 0, sourcewidth * CYBERARRAY_BPP, scrrp, x, y, sourcewidth, sourceheight, RECTFMT_RGB);
  649.          ScalePixelArray (cyberdata, sourcewidth, sourceheight, sourcewidth * CYBERARRAY_BPP, &destrp, 0, 0, sourcewidth * scalefac, sourceheight * scalefac, RECTFMT_RGB);
  650.       }
  651.       else
  652.       {
  653.          BltBitMap (scrbm, x, y, srcbm, 0, 0, sourcewidth, sourceheight, ABNC | ABC, ~0, NULL);
  654.          BitMapScale (&bsa);
  655.       }
  656.       // draw the crosshair 
  657.       if (crosshair)
  658.       {
  659.          Move (&destrp, xoff, 0);
  660.          Draw (&destrp, xoff, sourceheight * scalefac - 1);
  661.          Move (&destrp, 0, yoff);
  662.          Draw (&destrp, sourcewidth * scalefac - 1, yoff);
  663.       }
  664.       mywin->Flags &= ~SIZEGADGET;
  665.       if ((winx == mywin->Width) && (winy == mywin->Height))
  666.          BltBitMapRastPort (destbm, 0, 0, winrp, leftoff, topoff, innerwidth, innerheight, ABNC | ABC);
  667.       mywin->Flags |= SIZEGADGET;
  668.    }
  669.    else
  670.    {
  671.       mywin->Flags &= ~SIZEGADGET;
  672.       if ((winx == mywin->Width) && (winy == mywin->Height))
  673.       {
  674.          BltBitMapRastPort (scrbm, x, y, winrp, leftoff, topoff, innerwidth, innerheight, ABNC | ABC);
  675.          // draw the crosshair in 1:1 - mode
  676.          if (crosshair)
  677.          {
  678.             SetDrMd (winrp, COMPLEMENT);
  679.             Move (winrp, leftoff + xoff, topoff);
  680.             Draw (winrp, leftoff + xoff, topoff + innerheight - 1);
  681.             Move (winrp, leftoff, topoff + yoff);
  682.             Draw (winrp, leftoff + innerwidth - 1, topoff + yoff);
  683.             SetDrMd (winrp, JAM2);
  684.          }
  685.       }
  686.       mywin->Flags |= SIZEGADGET;
  687.    }
  688. }
  689.  
  690. void CxFunction (CxMsg *cxm, CxObj *co)
  691. {
  692.  struct InputEvent *ie = (struct InputEvent *) CxMsgData (cxm);
  693.  
  694.    if (origin)
  695.    {
  696.       if (MatchIX (ie, &setoriginix))
  697.       {
  698.          originX = scr->MouseX;
  699.          originY = scr->MouseY;
  700.          DisposeCxMsg (cxm);
  701.          return;
  702.       }
  703.       if (MatchIX (ie, &resetoriginix))
  704.       {
  705.          originX = originY = 0;
  706.          DisposeCxMsg (cxm);
  707.          return;
  708.       }
  709.    }
  710.    if ((ie->ie_Class == IECLASS_TIMER) || fast)
  711.       Signal (thistask, 1 << timesig);
  712. }
  713.  
  714. BOOL initbroker ()
  715. {
  716.  LONG errorcode;
  717.  
  718.    if (broker_mp = CreateMsgPort ())
  719.    {
  720.       newbroker.nb_Port = broker_mp;
  721.       cxsigflag = 1 << broker_mp->mp_SigBit;
  722.       if (broker = CxBroker (&newbroker, &errorcode))
  723.       {
  724.          if (customcxobj = CxCustom (CxFunction, 0))
  725.          {
  726.             if (!CxObjError (customcxobj))
  727.             {
  728.                AttachCxObj (broker, customcxobj);
  729.                if (ParseIX (setoriginkey, &setoriginix) || ParseIX (resetoriginkey, &resetoriginix))
  730.                {
  731.                   origin = FALSE;
  732.                   error ("Can't init Hotkeys.\n'Set Origin' disabled.");
  733.                }
  734.                ActivateCxObj (broker, 1);
  735.                return TRUE;
  736.             }
  737.             DeleteCxObj (customcxobj);
  738.          }
  739.          else error ("Can't create commodity-custom-objekt.");
  740.          DeleteCxObjAll (broker);
  741.       }
  742.       else if (errorcode == CBERR_SYSERR)
  743.          error ("Can't create commodity-broker-objekt.");
  744.       DeleteMsgPort (broker_mp);
  745.    }
  746.    else error ("Can't create messageport for commodity-broker");
  747.    return FALSE;
  748. }
  749.  
  750. // enable-flag only
  751. void setmenu ()
  752. {
  753.  struct MenuItem *mitem;
  754.  
  755.    ClearMenuStrip (mywin);
  756.    mitem = ItemAddress (menu, FULLMENUNUM (0, 3, NOSUB));
  757.    if (enable) mitem->Flags |= CHECKED;
  758.       else mitem->Flags &= ~CHECKED;
  759.    ResetMenuStrip (mywin, menu);
  760. }
  761.  
  762. BOOL reopenwin ()
  763. {
  764.    waitmask &= ~(1 << userport->mp_SigBit);
  765.    wintop = mywin->TopEdge;
  766.    winleft = mywin->LeftEdge;
  767.    closewin ();
  768.    getoffsets ();
  769.    if (!openwin ()) return FALSE;
  770.    waitmask |= 1 << userport->mp_SigBit;
  771.    if (allocbm ()) return FALSE;
  772.    jump = TRUE;
  773.    return TRUE;
  774. }
  775.  
  776. BOOL setpropgad ()
  777. {
  778.    if (allocbm ()) return FALSE;
  779.    SetAttrs (propgadget, PGA_Top, scalefac - 1);
  780.    RefreshGList ((struct Gadget *) propgadget, mywin, NULL, 1);
  781.     setwintitle ();
  782.    return TRUE;
  783. }
  784.  
  785. void processmsg ()
  786. {
  787.  struct IntuiMessage *intuimsg = NULL, m;
  788.  CxMsg *msg;
  789.  BOOL cont = TRUE, fixedmove = FALSE;
  790.  LONG sigmask, msgid, msgtype;;
  791.  UWORD code;
  792.  ULONG lock;
  793.  static BOOL (*func)();
  794.  
  795.    waitmask = (1 << userport->mp_SigBit) | (1 << timesig) | cxsigflag | SIGBREAKF_CTRL_C;
  796.    while (cont)
  797.    {
  798.       sigmask = Wait (waitmask);
  799.       if (sigmask & cxsigflag)
  800.       {
  801.          while (msg = (CxMsg *) GetMsg (broker_mp))
  802.          {
  803.             msgid = CxMsgID (msg);
  804.             msgtype = CxMsgType (msg);
  805.             ReplyMsg ((struct Message *) msg);
  806.             switch (msgtype)
  807.             {
  808.              case CXM_COMMAND:
  809.                switch (msgid)
  810.                {
  811.                 case CXCMD_DISABLE:
  812.                   ActivateCxObj (broker, 0);
  813.                   enable = FALSE;
  814.                   setmenu ();
  815.                   break;
  816.                 case CXCMD_ENABLE:
  817.                   ActivateCxObj (broker, 1);
  818.                   enable = TRUE;
  819.                   setmenu ();
  820.                   break;
  821.                 case CXCMD_UNIQUE:
  822.                 case CXCMD_KILL:
  823.                   cont = FALSE;
  824.                   break;
  825.                }
  826.             }
  827.          }
  828.       }
  829.       if (sigmask & (1 << userport->mp_SigBit))
  830.       {
  831.          jump = FALSE;
  832.          while (intuimsg = (struct IntuiMessage *) GetMsg (userport))
  833.          {
  834.             CopyMem ((char *) intuimsg, (char *) &m, (long) sizeof (struct IntuiMessage));
  835.             ReplyMsg ((struct Message *) intuimsg);
  836.             switch (m.Class)
  837.             {
  838.              case IDCMP_CLOSEWINDOW:
  839.                cont = FALSE;
  840.                break;
  841.              case IDCMP_NEWSIZE:
  842.                if (allocbm ()) cont = FALSE;
  843.                break;
  844.              case IDCMP_IDCMPUPDATE:
  845.                ULONG h;
  846.                GetAttr (PGA_Top, propgadget, &h);
  847.                if (++h != scalefac)
  848.                {
  849.                   scalefac = h;
  850.                   if (allocbm ()) cont = FALSE;
  851.                   setwintitle ();
  852.                }
  853.                break;
  854.              case IDCMP_MENUPICK:
  855.                code = m.Code;
  856.                while ((code != MENUNULL) && cont && !jump)
  857.                {
  858.                   item = ItemAddress (menu, code);
  859.                   if (SUBNUM (code) != NOSUB)
  860.                   {
  861.                      if (GTMENUITEM_USERDATA (item))  // 'no other screen' - submenu
  862.                      {
  863.                         try
  864.                         {
  865.                            if (setupscreen ((struct Screen *) GTMENUITEM_USERDATA (item))) throw 1;
  866.                            waitmask &= ~(1 << userport->mp_SigBit);
  867.                            wintop = mywin->TopEdge;
  868.                            winleft = mywin->LeftEdge;
  869.                            closewin ();
  870.                            getoffsets ();
  871.                            if (!openwin ()) throw 2;
  872.                            waitmask |= 1 << userport->mp_SigBit;
  873.                            if (allocbm ()) throw 3;
  874.                         }
  875.                         catch (int)
  876.                         {
  877.                            cont = FALSE;
  878.                         }
  879.                         jump = TRUE;
  880.                      }
  881.                   }
  882.                   else
  883.                   {
  884.                      func = (BOOL (*)()) GTMENUITEM_USERDATA (item);
  885.                      cont = func ();
  886.                   }
  887.                   if (!jump) code = item->NextSelect;
  888.                }
  889.                break;
  890.              case IDCMP_ACTIVEWINDOW:
  891.                SetAPen (winrp, pens[0]);
  892.                SetBPen (winrp, pens[1]);
  893.                ClearMenuStrip (mywin);
  894.                freescreensmenu (ItemAddress (menu, FULLMENUNUM (0, 1, 0)));
  895.                if (makescreensmenu ()) SetMenuStrip (mywin, menu);
  896.                else cont = FALSE;
  897.                break;
  898.              case IDCMP_INACTIVEWINDOW:
  899.                SetAPen (winrp, pens[2]);
  900.                SetBPen (winrp, pens[3]);
  901.                break;
  902.              case IDCMP_MOUSEBUTTONS:
  903.                if (fixed)
  904.                {
  905.                   if (m.Code == SELECTDOWN) fixedmove = TRUE;
  906.                   else fixedmove = FALSE;
  907.                }
  908.                break;
  909.              case IDCMP_MOUSEMOVE:
  910.                if (fixedmove)
  911.                {
  912.                   fixedX = scr->MouseX;
  913.                   fixedY = scr->MouseY;
  914.                }
  915.                break;
  916.              case IDCMP_VANILLAKEY:
  917.                switch (m.Code)
  918.                {
  919.                 case 'J':
  920.                 case 'j':
  921.                   cont = jumpFunc ();
  922.                   break;
  923.                 case 'E':
  924.                 case 'e':
  925.                   enable = !enable;
  926.                   ActivateCxObj (broker, enable);
  927.                   setmenu ();
  928.                 case 'F':
  929.                 case 'f':
  930.                   fast = !fast;
  931.                   break;
  932.                 case 'C':
  933.                 case 'c':
  934.                   coords = !coords;
  935.                   cont = reopenwin ();
  936.                   break;
  937.                 case 'R':
  938.                 case 'r':
  939.                   crosshair = !crosshair;
  940.                   break;
  941.                 case 'O':
  942.                 case 'o':
  943.                   originX = scr->MouseX;
  944.                   originY = scr->MouseY;
  945.                   break;
  946.                 case 'K':
  947.                 case 'k':
  948.                   originX = originY = 0;
  949.                   break;
  950.                 case 'D':
  951.                 case 'd':
  952.                   fixed = !fixed;
  953.                   break;
  954.                 case '?':
  955.                 case 'A':
  956.                 case 'a':
  957.                     AboutFunc ();
  958.                   break;
  959.                 case 'Q':
  960.                 case 'q':
  961.                 case 27:
  962.                   cont = FALSE;
  963.                   break;
  964.                 case '+':
  965.                   if (scalefac < maxscalefac)
  966.                   {
  967.                      scalefac++;
  968.                      cont = setpropgad ();
  969.                   }
  970.                   break;
  971.                 case '-':
  972.                   if (scalefac > 1)
  973.                   {
  974.                      scalefac--;
  975.                      cont = setpropgad ();
  976.                   }
  977.                   break;
  978.                }
  979.                break;
  980.              case IDCMP_RAWKEY:
  981.                switch (m.Code)
  982.                {
  983.                 // up
  984.                 case 76:
  985.                     if (m.Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  986.                   {
  987.                      fixedY -= sourceheight - 1;
  988.                      if (fixedY < 0) fixedY = 0;
  989.                   }
  990.                   else if (m.Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  991.                   {
  992.                      fixedY = 0;
  993.                   }
  994.                     else if (fixedY) fixedY--;
  995.                   break;
  996.                 // down
  997.                 case 77:
  998.                     if (m.Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  999.                   {
  1000.                      fixedY += sourceheight - 1;
  1001.                      if (fixedY > (scr->Height - 1)) fixedY = scr->Height - 1;
  1002.                   }
  1003.                   else if (m.Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  1004.                   {
  1005.                      fixedY = scr->Height - 1;
  1006.                   }
  1007.                     else if (fixedY < (scr->Height - 1)) fixedY++;
  1008.                   break;
  1009.                 // right
  1010.                 case 78:
  1011.                     if (m.Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1012.                   {
  1013.                      fixedX += sourcewidth - 1;
  1014.                      if (fixedX > (scr->Width - 1)) fixedX = scr->Width - 1;
  1015.                   }
  1016.                   else if (m.Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  1017.                   {
  1018.                      fixedX = scr->Width - 1;
  1019.                   }
  1020.                     else if (fixedX < (scr->Width - 1)) fixedX++;
  1021.                   break;
  1022.                 // left
  1023.                 case 79:
  1024.                     if (m.Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1025.                   {
  1026.                      fixedX -= sourcewidth - 1;
  1027.                      if (fixedX < 0) fixedX = 0;
  1028.                   }
  1029.                   else if (m.Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  1030.                   {
  1031.                      fixedX = 0;
  1032.                   }
  1033.                     else if (fixedX) fixedX--;
  1034.                   break;
  1035.                }
  1036.             }
  1037.          }
  1038.       }
  1039.       if ((sigmask & (1 << timesig)) && cont)
  1040.       {
  1041.          // refresh only if we living on the active screen
  1042.          lock = LockIBase (0);
  1043.          tmpscr = IntuitionBase->ActiveScreen;
  1044.          UnlockIBase (lock);
  1045.          if (scr == tmpscr) refresh ();
  1046.       }
  1047.       if (sigmask & SIGBREAKF_CTRL_C)
  1048.       {
  1049.          cont = FALSE;
  1050.       }
  1051.    }
  1052. }
  1053.  
  1054. BOOL checkmenuitem (BOOL &value)
  1055. {
  1056.    if (!value && (item->Flags & CHECKED)) value = TRUE;
  1057.    else if (value && !(item->Flags & CHECKED)) value = FALSE;
  1058.    return TRUE;   
  1059. }
  1060.  
  1061. BOOL fixedFunc ()
  1062. {
  1063.    return checkmenuitem (fixed);   
  1064. }
  1065.  
  1066. BOOL fastFunc ()
  1067. {
  1068.    return checkmenuitem (fast);   
  1069. }
  1070.  
  1071. BOOL crosshairFunc ()
  1072. {
  1073.    return checkmenuitem (crosshair);
  1074. }
  1075.  
  1076. BOOL AboutFunc ()
  1077. {
  1078.    EasyRequestArgs (NULL, &es_about, NULL, era_about);
  1079.    return TRUE;
  1080. }
  1081.  
  1082. BOOL jumpFunc ()
  1083. {
  1084.  int returnvalue;
  1085.  
  1086.    if (!(returnvalue = setupscreen (NULL)))
  1087.    {
  1088.       return reopenwin ();
  1089.    }
  1090.    else if (returnvalue == 1) return TRUE;      // no other screen
  1091.    return FALSE;
  1092. }
  1093.    
  1094. BOOL coordsFunc ()
  1095. {
  1096.    if (!coords && (item->Flags & CHECKED)) coords = TRUE;
  1097.    else if (coords && !(item->Flags & CHECKED)) coords = FALSE;
  1098.    else return TRUE;  // nothing changed
  1099.    return reopenwin ();
  1100. }
  1101.  
  1102. BOOL enableFunc ()
  1103. {
  1104.    if (item->Flags & CHECKED)
  1105.    {
  1106.       ActivateCxObj (broker, 1);
  1107.       enable = TRUE;
  1108.    }
  1109.    else if (!(item->Flags & CHECKED))
  1110.    {
  1111.       ActivateCxObj (broker, 0);
  1112.       enable = FALSE;
  1113.    }
  1114.    return TRUE;   
  1115. }
  1116.  
  1117. BOOL QuitFunc ()
  1118. {
  1119.    return FALSE;
  1120. }
  1121.  
  1122. BOOL argbool (char **argv, char *name, BOOL def)
  1123. {
  1124. char *value;
  1125.    
  1126.    if (value = (char *) FindToolType ((UBYTE **) argv, name))
  1127.    {
  1128.       if ((MatchToolValue (value, "YES")) || (MatchToolValue (value, "ON"))) return TRUE;
  1129.       if ((MatchToolValue (value, "OFF")) || (MatchToolValue (value, "NO"))) return FALSE;
  1130.    }
  1131.    return def;
  1132. }
  1133.  
  1134. LONG argint (char **argv, UBYTE *name, LONG def)
  1135. {
  1136. APTR value;
  1137. LONG returnvalue;
  1138.  
  1139.    if (value = FindToolType ((UBYTE **) argv, name))
  1140.       if (StrToLong ((UBYTE *) value, &returnvalue)) return returnvalue;
  1141.    return def;
  1142. }
  1143.  
  1144. void argstring (char *result, char **argv, char *name)
  1145. {
  1146.  char *value;
  1147.    
  1148.    if (value = FindToolType ((UBYTE **) argv, name))
  1149.       strncpy (result, value, 50);
  1150. }
  1151.  
  1152. void readargs ()
  1153. {
  1154.  // first time always the tooltypes will be evaluated
  1155.  // if we started from Cli the tooltypes can be overloaded
  1156.  char programname[32];
  1157.  char **argv;
  1158.  struct DiskObject *programicon;
  1159.  struct RDArgs * rdargs;
  1160.  LONG args[13];
  1161.  struct DrawInfo *drawinfo;
  1162.  
  1163.    wintop = scr->RastPort.TxHeight + (UWORD) scr->WBorTop + 1; 
  1164.    // make window as square as possible
  1165.    if (drawinfo = GetScreenDrawInfo (scr))
  1166.    {
  1167.       innerheight = innerwidth * drawinfo->dri_Resolution.X / drawinfo->dri_Resolution.Y;
  1168.       FreeScreenDrawInfo (scr, drawinfo);
  1169.    }
  1170.    // a Maxon C++ flag (wbstartup.h)
  1171.    if (_wbflag) strcpy (programname, thistask->tc_Node.ln_Name);
  1172.    else GetProgramName (programname, 32);
  1173.    if (IconBase = OpenLibrary ("icon.library", 37))
  1174.    {
  1175.       if (programicon = GetDiskObject (programname))
  1176.       {
  1177.          argv = programicon->do_ToolTypes;
  1178.          newbroker.nb_Pri = argint (argv, "CX_Priority", newbroker.nb_Pri);
  1179.          fast = argbool (argv, "Fast", fast);
  1180.          maxscalefac = argint (argv, "MaxScaleFactor", maxscalefac);
  1181.          scalefac = argint (argv, "ScaleFactor", scalefac);
  1182.          winleft = argint (argv, "WinLeft", winleft);
  1183.          wintop = argint (argv, "WinTop", wintop);
  1184.          innerheight = argint (argv, "WinHeight", innerheight);
  1185.          innerwidth = argint (argv, "WinWidth", innerwidth);
  1186.          coords = argbool (argv, "Coordinates", coords);
  1187.          crosshair = argbool (argv, "Crosshair", crosshair);
  1188.          argstring (setoriginkey, argv, "SetOriginKey");
  1189.          argstring (resetoriginkey, argv, "ResetOriginKey");
  1190.          argbool (argv, "Fixed", fixed);
  1191.          FreeDiskObject (programicon);
  1192.       }
  1193.       CloseLibrary (IconBase);
  1194.    }
  1195.    if (Cli ())
  1196.    {
  1197.       memset (args, '\0', sizeof (args));
  1198.       args[1] = fast;
  1199.       args[8] = coords;
  1200.       args[9] = crosshair;
  1201.       args[12] = fixed;
  1202.       if (rdargs = ReadArgs (Template, args, NULL))
  1203.       {
  1204.          if (args[0]) newbroker.nb_Pri = *(LONG *) args[0];
  1205.          fast = args[1];
  1206.          if (args[2]) maxscalefac = *(LONG *) args[2];
  1207.          if (args[3]) scalefac = *(LONG *) args[3];
  1208.          if (args[4]) winleft = *(LONG *) args[4];
  1209.          if (args[5]) wintop = *(LONG *) args[5];
  1210.          if (args[6]) innerwidth = *(LONG *) args[6];
  1211.          if (args[7]) innerheight = *(LONG *) args[7];
  1212.          coords = args[8];
  1213.          crosshair = args[9];
  1214.          if (args[10]) strcpy (setoriginkey, (char *) args[10]);
  1215.          if (args[11]) strcpy (resetoriginkey, (char *) args[11]);
  1216.          fixed = args[12];
  1217.          FreeArgs (rdargs);
  1218.       }
  1219.    }
  1220.    if (maxscalefac < 5) maxscalefac = 5;
  1221.    // not lower than innerheight or innerwidth
  1222.    // otherwise 'innerheight / scalefac' or 'innerwidth / scalefac'
  1223.    // can go to 0 -> 'AllocBitMap ()' failed
  1224.    if (maxscalefac > MINHEIGHT) maxscalefac = MINHEIGHT;
  1225.    if (scalefac > maxscalefac) scalefac = maxscalefac;
  1226.    if (innerheight < MINHEIGHT) innerheight = MINHEIGHT;
  1227.    if (innerwidth < MINWIDTH) innerwidth = MINWIDTH;
  1228. }
  1229.  
  1230. void main ()
  1231. {
  1232.    if (CxBase = OpenLibrary ("commodities.library", 37))
  1233.    {
  1234.       if (GfxBase = OpenLibrary ("graphics.library", 39))
  1235.       {
  1236.          if (GadToolsBase = OpenLibrary ("gadtools.library", 37))
  1237.          {
  1238.             CyberGfxBase = OpenLibrary ("cybergraphics.library", 40);
  1239.             InitRastPort (&destrp);
  1240.             SetDrMd (&destrp, COMPLEMENT);
  1241.             thistask = FindTask (NULL);
  1242.             if (topazfont = OpenFont (&topaz_attr))
  1243.             {
  1244.                if (!setupscreen (NULL))
  1245.                {
  1246.                   readargs ();
  1247.                   getoffsets ();
  1248.                   if (openwin ())
  1249.                   {
  1250.                      if (!allocbm ())
  1251.                      {
  1252.                         if ((timesig = AllocSignal (-1L)) != -1)
  1253.                         {
  1254.                            if (initbroker ())
  1255.                            {
  1256.                               processmsg ();
  1257.                               DeleteCxObjAll (broker);
  1258.                               DeleteMsgPort (broker_mp);
  1259.                            }
  1260.                            FreeSignal (timesig);
  1261.                         }
  1262.                         else error ("Can't allocate signal");
  1263.                      } 
  1264.                      closewin ();
  1265.                   }
  1266.                   CloseDownScreen ();
  1267.                }
  1268.                CloseFont (topazfont);
  1269.                if (screenfont) CloseFont (screenfont);
  1270.             }
  1271.             else error ("Can't open Topas.font");
  1272.             if (CyberGfxBase) CloseLibrary (CyberGfxBase);
  1273.             CloseLibrary (GadToolsBase);
  1274.          }
  1275.          else error ("can't open '%s' version %ld or higher.", "gadtools.library", 37L);
  1276.          CloseLibrary (GfxBase);
  1277.       }
  1278.       else error ("can't open '%s' version %ld or higher.", "graphics.library", 39L);
  1279.       CloseLibrary (CxBase);
  1280.    }
  1281.    else error ("can't open '%s' version %ld or higher.", "commodities.library", 37L);
  1282. }
  1283.  
  1284.